/**
 * @(#)Logic.java
 *
 * Copyright: Copyright (c) 2003 Carnegie Mellon University
 *
 * This program is the implementation of the original system in the Assignment 2 of "Architectures
 * of Software Systems" class. For the details of each classes, please refer to the provided javadoc
 * documents. You will also find some useful information such as implementation decisions, coding
 * standards, and naming conventions in the README file.
 */


import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;


/**
 * This class represents a logic node which is responsible for providing high-level data access
 * methods to clients using RMI mechanism. It depends on the functionalities of data node
 * which is made available also using RMI mechanism, thus acting as a "bridge" between client nodes
 * and the data node.
 *
 * @author Jung Soo Kim
 * @version 1.0
 */
public class Authorization extends UnicastRemoteObject implements RIAuthorization {

    private static final String Authorization_NAME = "Authorization";
    private static final String UserDATA_NAME  = "UserData";

    /**
     * Remote reference to data node.
     */
    protected RIUserData rmiUserDataNode;

    /**
     * Constructs a Authorization node. A remote reference to the data node is acquired at the time of
     * creation.
     *
     * @param sDataName the name of data node
     */
    public Authorization(String sDataName)
           throws RemoteException, NotBoundException, MalformedURLException {
        // Get the remote reference to data node.
        this.rmiUserDataNode = (RIUserData) Naming.lookup(sDataName);
    }

    /**
     * List all students.
     *
     * @return a string result of command processing
     */
    public String getCurUser()
    		throws RemoteException {
    	ArrayList vCurUser = this.rmiUserDataNode.getCurUserRecords();
    	if(vCurUser.size()<1)
    		return "NONE";
    	return ((String)vCurUser.get(vCurUser.size()-1));    	
    }
    public String getAllUsers()
                  throws RemoteException {
        // Get all student records.
        ArrayList vUser = this.rmiUserDataNode.getAllUserRecords();

        // Construct a list of student information and return it.
        String sReturn = "";
        for (int i=0; i<vUser.size(); i++) {
            sReturn += (i == 0 ? "" : "\n") + ((User) vUser.get(i)).toString();
        }
        return sReturn;
    }

    public int findUser(String sID)
    			throws RemoteException{
    	ArrayList vUser = this.rmiUserDataNode.getAllUserRecords();
    	int resultID = -1;
    	for(int i=0;i<vUser.size();i++){
    		if(((User) vUser.get(i)).match(sID))
    		{
    			
    			resultID = i;
    			break;
    		}
    	}
    	return resultID;    		
    }
    
    public boolean matchPasswd(String sID, String sPasswd)
			throws RemoteException{
		ArrayList vUser = this.rmiUserDataNode.getAllUserRecords();
		int resultID = -1;
		for(int i=0;i<vUser.size();i++){
			if(((User) vUser.get(i)).match(sID))
			{
				resultID = i;
				break;
			}
		}
		if(((User) vUser.get(resultID)).matchPasswd(sPasswd))
			this.rmiUserDataNode.addCurUser(sID);
		return ((User) vUser.get(resultID)).matchPasswd(sPasswd);
    }
    
    public void addUser(String sID, String sPasswd)
    		throws RemoteException{
    	this.rmiUserDataNode.addUserID(sID,sPasswd);
    	this.rmiUserDataNode.addCurUser(sID);
    }
    

    /**
     * Creates a Authorization node and starts it. Two parameters are expected, the first one as data node
     * name and the second one as Authorization node name.
     *
     * @param args array of input parameters
     */
    public static void main(String args[]) {
        // Check the number of parameters.
        if (args.length != 0) {
            System.out.println("Incorrect number of parameters");
            System.out.println("Usage: java Authorization");
            System.exit(1);
        }

        try {
            // Create a Authorization node and make it available through RMI.
            Authorization objAuthorization = new Authorization(UserDATA_NAME);
            Naming.rebind(Authorization_NAME, objAuthorization);
            System.out.println("Authorization node is ready to serve.");

            // Wait for user interrupt.
            System.out.println("Press Enter to terminate.");
            System.in.read();

            // Clean up and finish.
            Naming.unbind(Authorization_NAME);
            System.out.println("Authorization node is leaving, bye. Press ctrl-c if the delay is too long.");
        }
        catch (java.rmi.ConnectException e) {
            // Show error message and quit.
            System.err.println("Java RMI error: check if rmiregistry is running.");
            System.exit(1);
	}
        catch (java.rmi.NotBoundException e) {
            // Show error message and quit.
            System.err.println("Java RMI error: check if data node is running.");
            System.exit(1);
        }
        catch (Exception e) {
            // Dump the exception information for debugging.
            System.out.println("Unexpected exception at " + Authorization_NAME);
            e.printStackTrace();
            System.exit(1);
        }
    }
}
